package com.ruoyi.common.utils.shandianbao;

import com.alibaba.fastjson.JSONObject;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author luobo
 * @title: ThreeDES
 * @projectName pos
 * @description: TODO
 * @date 2022-04-01 09:06:00
 */
public class ThreeDES {
    private static final String IV = "12345678";

    /**
     * DESCBC加密
     *
     * @param src
     *            数据源
     * @param key
     *            密钥，长度必须是8的倍数
     * @return 返回加密后的数据TUserInfoServiceImpl
     * @throws Exception
     */
    public String encryptDESCBC(final String src, final String key) throws Exception {

        // --生成key,同时制定是des还是DESede,两者的key长度要求不同
        final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        final SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

        // --加密向量
        final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));

        // --通过Chipher执行加密得到的是一个byte的数组,Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.ENCRYPT_MODE,
        // secretKey)就可以了.
        final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
        final byte[] b = cipher.doFinal(src.getBytes("UTF-8"));

        // --通过base64,将加密数组转换成字符串
        final BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(b);
    }

    /**
     * DESCBC解密
     *
     * @param src
     *            数据源
     * @param key
     *            密钥，长度必须是8的倍数
     * @return 返回解密后的原始数据
     * @throws Exception
     */
    public String decryptDESCBC(final String src, final String key) throws Exception {
        // --通过base64,将字符串转成byte数组
        final BASE64Decoder decoder = new BASE64Decoder();
        final byte[] bytesrc = decoder.decodeBuffer(src);

        // --解密的key
        final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        final SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

        // --向量
        final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));

        // --Chipher对象解密Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.DECRYPT_MODE,
        // secretKey)就可以了.
        final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
        final byte[] retByte = cipher.doFinal(bytesrc);

        return new String(retByte);

    }

    // 3DESECB加密,key必须是长度大于等于 3*8 = 24 位哈
    public static String encryptThreeDESECB(final String src, final String key) throws Exception {
        final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        final SecretKey securekey = keyFactory.generateSecret(dks);

        final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, securekey);
        final byte[] b = cipher.doFinal(src.getBytes());

        final BASE64Encoder encoder = new BASE64Encoder();
        return encoder.encode(b).replaceAll("\r", "").replaceAll("\n", "");

    }

    // 3DESECB解密,key必须是长度大于等于 3*8 = 24 位哈
    public static String decryptThreeDESECB(final String src, final String key) throws Exception {
        // --通过base64,将字符串转成byte数组
        final BASE64Decoder decoder = new BASE64Decoder();
        final byte[] bytesrc = decoder.decodeBuffer(src);
        // --解密的key
        final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
        final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        final SecretKey securekey = keyFactory.generateSecret(dks);

        // --Chipher对象解密
        final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, securekey);
        final byte[] retByte = cipher.doFinal(bytesrc);

        return URLDecoder.decode(new String(retByte), "utf-8");
    }

    public static String test() throws Exception {
        //rugrId：3     saruLruid:1008013255    key：7560654CD81AED8541B05F1245714123
        //地址：http://112.124.6.222:8080/sdbpl-mobile/

        final String key = "7560654CD81AED8541B05F1245714123";
        // 加密流程
        JSONObject jo = new JSONObject();
        jo.put("rugrId", "3");
        jo.put("beginTime", "2021-10-28 14:24:30");
        jo.put("endTime", "2021-10-28 17:39:33");
        //jo.put("phoneNo", "15899874068");
        ThreeDES threeDES = new ThreeDES();
        String telePhone_encrypt = "";
        System.out.println("原始请求参数" + jo.toJSONString());
        //telePhone_encrypt = threeDES.encryptThreeDESECB(URLEncoder.encode(jo.toJSONString(), "UTF-8"), key);
        telePhone_encrypt = threeDES.encryptThreeDESECB(jo.toJSONString(), key);
        //System.out.println("===="+telePhone_encrypt);// nWRVeJuoCrs8a+Ajn/3S8g==

        // 解密流程
        String tele_decrypt = threeDES.decryptThreeDESECB(telePhone_encrypt, key);
        //System.out.println("模拟代码解密:" + tele_decrypt);
        //System.out.println("模拟代码解密:" + URLDecoder.decode(tele_decrypt, "utf-8"));
        return telePhone_encrypt;
    }

    public static void main(String[] args) throws UnsupportedEncodingException {

        JSONObject json = new JSONObject();
        json.put("rugrId","3");
        json.put("beginTime","2022-02-10 12:40:43");
        json.put("endTime","2022-02-10 15:40:43");
        String signString = Des3Util.encode(json.toJSONString(), "7560654CD81AED8541B05F1245714123");
        Map<String, String> par = new LinkedHashMap<String, String>();
        par.put("params", signString);
        try {
            String result = MobileHttpClient.postParameters("http://112.124.6.222:8080/sdbpl-mobile/channel/queryInfoChannel/queryRegisterInfo", par);
            System.out.println(result);
        } catch (Exception e) {
        }
    }

}
